package com.feature.core.config;

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.config.ContainerCustomizer;
import org.springframework.amqp.rabbit.core.CorrelationDataPostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnsCallback;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.feature.core.rabbitmq.AfterReceivePostProcessor;
import com.feature.core.rabbitmq.BeforeSendDataPostProcessor;
import com.feature.core.rabbitmq.FastJson2MessageConverter;
import com.feature.core.rabbitmq.LogConfirmCallback;
import com.feature.core.rabbitmq.LogConsumeErrorHandle;
import com.feature.core.rabbitmq.LogMessageRecoverer;
import com.feature.core.rabbitmq.LogReturnsCallback;
import com.feature.core.rabbitmq.RabbitMqPropertiesBeanPostProcessor;

@Configuration
public class RabbitMqAutoConfigure {

    @Bean
    public RabbitMqPropertiesBeanPostProcessor rabbitMqPropertiesBeanPostProcessor() {
        return new RabbitMqPropertiesBeanPostProcessor();
    }

    @Bean
    public MessageConverter messageConverter() {
        FastJson2MessageConverter converter = new FastJson2MessageConverter();
        converter.setCreateMessageIds(true);
        return converter;
    }

    /**
     * 发送确认回调
     * 
     * @return
     * @author wangzhiyue
     * @date 2024/07/26 17:41:27
     */
    @Bean
    @ConditionalOnMissingBean(ConfirmCallback.class)
    public ConfirmCallback logConfirmCallback() {
        return new LogConfirmCallback();
    }

    /**
     * 发送到broke，但没有匹配到队列的回调
     * 
     * @return
     * @author wangzhiyue
     * @date 2024/07/26 17:41:37
     */
    @Bean
    @ConditionalOnMissingBean(ReturnsCallback.class)
    public ReturnsCallback logReturnsCallback() {
        return new LogReturnsCallback();
    }

    /**
     * 发送前处理
     * 
     * @return
     * @author wangzhiyue
     * @date 2024/07/26 17:42:18
     */
    @Bean
    @ConditionalOnMissingBean(CorrelationDataPostProcessor.class)
    public CorrelationDataPostProcessor traceIdCorrelationDataPostProcessor() {
        return new BeforeSendDataPostProcessor();
    }

    /**
     * 重试n次消费失败处理
     * 
     * @return
     * @author wangzhiyue
     * @date 2024/07/26 17:42:35
     */
    @Bean
    @ConditionalOnMissingBean(MessageRecoverer.class)
    public MessageRecoverer LogMessageRecoverer() {
        return new LogMessageRecoverer();
    }

    /**
     * 接收方处理消息前拦截处理
     * 
     * @return
     * @author wangzhiyue
     * @date 2024/07/26 17:43:38
     */
    @Bean
    @ConditionalOnMissingBean(MessagePostProcessor.class)
    MessagePostProcessor traceIdAfterReceivePostProcessor() {
        return new AfterReceivePostProcessor();
    }

    @Bean
    public ContainerCustomizer<SimpleMessageListenerContainer> simpleMessageListenerContainerContainerCustomizer(MessagePostProcessor messagePostProcessor) {
        return new ContainerCustomizer<SimpleMessageListenerContainer>() {

            @Override
            public void configure(SimpleMessageListenerContainer container) {
                container.setErrorHandler(new LogConsumeErrorHandle());
                if (messagePostProcessor != null) {
                    container.setAfterReceivePostProcessors(messagePostProcessor);
                }
                container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
            }
        };
    }
}
